package com.heima.behavoir.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.behavoir.service.BehaviorService;
import com.heima.common.constants.BehaviorConstants;
import com.heima.common.constants.HotArticleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.behavior.dtos.BehaviorDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.UpdateArticleMess;
import com.heima.utils.thread.BehaviorThreadLocalUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class BehaviorServiceImpl implements BehaviorService {
    @Autowired
    // private RedisTemplate<String, Map<String, Integer>> redisTemplate;
    private RedisTemplate redisTemplate;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 点赞 或 取消
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(BehaviorDto dto) {
        //1、参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.okResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2、业务处理
        //2.1、取出当前用户id
        Integer userId = BehaviorThreadLocalUnit.get();

        //创建kafka消息传递对象
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setType(UpdateArticleMess.UpdateArticleType.LIKES);
        mess.setArticleId(dto.getArticleId());
        //2.2、redis 存储点赞行为，异或取消
//        Map<String, Integer> map = (Map<String, Integer>) redisTemplate.opsForValue().get(userId + "_" + dto.getArticleId());
//        handleBehavior(userId, dto, map, "operation", dto.getOperation());
        if (dto.getOperation().equals(0)) {
            //2.3、点赞了就储存哈希值（对象）
            cacheService.hPut(userId + "_" + dto.getArticleId(), "operation", dto.getOperation().toString());
            mess.setAdd(1);
        }
        if (dto.getOperation().equals(1)) {
            //取消点赞
            cacheService.hDelete(userId + "_" + dto.getArticleId(), "operation");
            mess.setAdd(-1);
        }
        //3、往kafka里发送消息 article微服务监听
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, JSON.toJSONString(mess));
        //4、响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 处理行为逻辑
     *
     * @param userId 用户id
     * @param dto    前端参数 主要用文章id
     * @param map    存入redis的值
     * @param key    map的键
     * @param value  map的值
     */
    private void handleBehavior(Integer userId, BehaviorDto dto, Map<String, Integer> map, String key, Integer value) {
        if (map == null) {
            map = new HashMap<>();
        }
        map.put(key, value);
        redisTemplate.opsForValue().set(userId + "_" + dto.getArticleId(), map);
    }

    /**
     * 不喜欢 或 取消
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult unLike(BehaviorDto dto) {
        //1、参数校验
        if (dto == null || dto.getArticleId() == null || dto.getType() == null) {
            return ResponseResult.okResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2、业务处理
        //2.1、取出当前用户id
        Integer userId = BehaviorThreadLocalUnit.get();
        //2.2、redis 存不喜欢操作，异或取消
//        Map<String, Integer> map = (Map<String, Integer>) redisTemplate.opsForValue().get(userId + "_" + dto.getArticleId());
//        handleBehavior(userId, dto, map, "unlike", dto.getType());
        //2.2、redis储存不喜欢
        if (dto.getType().equals(0)) {
            cacheService.hPut(userId + "_" + dto.getArticleId(), "unlike", dto.getType().toString());
        }
        //2.3、取消不喜欢，直接删除对应的值
        if (dto.getType().equals(1)) {
            cacheService.hDelete(userId + "_" + dto.getArticleId(), "unlike");
        }
        // 往kafka发送消息 article监听
        kafkaTemplate.send(BehaviorConstants.UN_LIKE_TOPIC,JSON.toJSONString(dto));
        //3、响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 阅读次数
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult read(BehaviorDto dto) {
        //1、参数校验
        if (dto == null || dto.getArticleId() == null || dto.getCount() == null) {
            return ResponseResult.okResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2、业务处理
        //2.1、取出当前用户id
        Integer userId = BehaviorThreadLocalUnit.get();
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setType(UpdateArticleMess.UpdateArticleType.VIEWS);
        /*// 记录该用户阅读次数  todo
        int count;
        Map<String, Integer> map1 = (Map<String, Integer>) redisTemplate.opsForValue().get(userId + "_" + dto.getArticleId());
        if (map1 == null) {
            //说明第一次进来
            map1 = new HashMap<>();
            map1.put("count", 1);
        } else {
            //这一次加上之前的
            Integer count1 = map1.get("count");
            count = count1 + dto.getCount();
            //存回去
            map1.put("count", count);
        }

        //2.3、redis 存储阅读行为，
        // 存入redis
        redisTemplate.opsForValue().set(userId + "_" + dto.getArticleId(), map1);*/
        //2.2、判断redis对应的哈希值是否有值
        Integer count;
        if (!cacheService.hExists(userId + "_" + dto.getArticleId(), "count")) {
            // 没有 说明是第一次
            cacheService.hPut(userId + "_" + dto.getArticleId(), "count", dto.getCount().toString());
        } else {
            // 不是第一次，取出来后加1再放回
            String countStr = cacheService.hGet(userId + "_" + dto.getArticleId(), "count").toString();
            count = Integer.parseInt(countStr) + dto.getCount();
            cacheService.hPut(userId + "_" + dto.getArticleId(),"count",count.toString());
        }
        mess.setAdd(1);
        mess.setArticleId(dto.getArticleId());
        //往kafka发送消息 artcile监听
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC,JSON.toJSONString(mess));
        //返回响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
